package App.Public.Lib;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.ArrayList;

/**
 * 提供一个普遍的搜索方法
 */
public class SearchUtil
{
    /**
     * 给定一定搜索数据，筛选出一切包含query属性的对象，并返回搜索结果
     * @param query         搜索条件
     * @param dataBase      搜索数据
     * @param searchRange   搜索范围（变量名）
     * @param baseResult    初始搜索结果
     * @param <E>           泛型，支持一切对象
     * @return              搜索结果
     */
    public static<E> ArrayList<E>search(String query,ArrayList<E>dataBase,ArrayList<String>searchRange,ArrayList<E>baseResult)
    {
        ArrayList<E>result=baseResult;
        for(E item:dataBase)
        {
            if(result.contains(item))
            {
                continue;
            }
            //遍历联系人对象的属性值，如果属性里面包含query查询关键词，就会认为符合条件，添加到result中，并且跳出该循环
            Class cls = item.getClass();
            Field[] fields = cls.getDeclaredFields();
            AccessibleObject.setAccessible(fields, true);
            for (Field field : fields)
            {
                if(!searchRange.contains(field.getName()))
                {
                    continue;
                }
                Object val = null;
                try {
                    val = field.get(item);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if(val==null) continue;
                if (val.toString().contains(query)) {
                    result.add(item);
                    break;
                }
            }
        }
        return result;
    }

    /**
     * 根据query对搜索数据进行搜索
     * @param query     搜索条件
     * @param dataBase  搜索数据
     * @param <E>       泛型
     * @return          搜索结果
     */
    public static<E> ArrayList<E>search(String query,ArrayList<E>dataBase)
    {
        ArrayList<String>searchRange=getAllSearchRange(dataBase.get(0));
        return search(query,dataBase,searchRange,new ArrayList<E>());
    }

    /**
     * 获取所有数据范围
     * @param o 目标对象
     * @return  数据范围
     */
    public static ArrayList<String> getAllSearchRange(Object o)
    {
        ArrayList<String>searchRange=new ArrayList<>();
        Class cls = o.getClass();
        Field[] fields = cls.getDeclaredFields();
        AccessibleObject.setAccessible(fields, true);
        for (Field field : fields)
        {
            searchRange.add(field.getName());
        }
        return searchRange;
    }
}
